﻿using Microsoft.AspNetCore.Mvc;

namespace Magic.System;

[Injection]
public class SysRoleService : ISysRoleService
{
    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public async Task<List<SysRoleTreeOutput>> GetTree(SysRolePageInput input)
    {
        var list = await SugarContext.Instance.Queryable<SysRole>()
                                                                 .WhereIF(!string.IsNullOrWhiteSpace(input.quick_search), 
                                                                       p => p.Name.Contains(input.quick_search))
                                                                 .Select<SysRoleTreeOutput>()
                                                                 .ToListAsync();
        list.ForEach(item =>
        {
            item.Permissions = item.Permissions == "*" ? "超级管理员" : $"{item.Permissions.Split(',').Length} 项权限";
        });
        return new TreeBuildUtil<SysRoleTreeOutput>().DoTreeBuild(list);
    }
    /// <summary>
    /// 获取角色权限
    /// </summary>
    /// <param name="ids">角色id集合</param>
    /// <returns></returns>
    public async Task<string> GetPermissionsByIds(List<int> ids)
    {
        List<string> rules = await SugarContext.Instance.Queryable<SysRole>()
                                                        .Where(m => ids.Contains(m.Id))
                                                        .Select(m => m.Permissions)
                                                        .ToListAsync();

        HashSet<string> hash = new HashSet<string>();
        rules.ForEach(rule =>
        {
            // 添加所有元素到 HashSet,HashSet 自动去重  
            hash.UnionWith(rule.Split(','));
        });

        return hash.ToArray().ParseToStrings<string>();
    }
    /// <summary>
    /// 分页返回角色
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public async Task<dynamic> GetPageList(SysRolePageInput input)
    {
        var adminGroups= await SugarContext.Instance.Queryable<SysRole>()
                                                               .Where(m => m.Status == StatusEnum.Enabled)
                                                               .OrderBy(p => p.Id)
                                                               .ToListAsync();
        //校验数据
        _ = adminGroups ?? throw new ApiException("当前查询无数据");
        //根据层级生成前缀
        int spanceCount = 1;//空格个数
        int pid = 0;
        string prexString=string.Empty; 
        adminGroups.ForEach(adminGroup =>
        {
            if(adminGroup.Pid!=0&&adminGroup.Pid!=pid)
            {
                prexString=string.Empty.PadRight(spanceCount, (char)32);
                pid=adminGroup.Pid;
                adminGroup.Name=string.Concat(prexString, string.Concat("└", adminGroup.Name));
                spanceCount++;
            }
            else if (adminGroup.Pid != 0 && adminGroup.Pid == pid)
            {
                adminGroup.Name = string.Concat(prexString, string.Concat("└", adminGroup.Name));
            }
        });
        return new
        {
            options = adminGroups
        };
    }
    /// <summary>
    /// 根据Id返回角色
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    public async Task<SysRoleDetailOutput> Get([FromQuery] int id)
    {
        var adminGroup = await SugarContext.Instance.Queryable<SysRole>().FirstAsync(p => p.Id == id);
        //数据校验
        _ = adminGroup ?? throw new ApiException("当前查询无数据");

        return new SysRoleDetailOutput
        {
            Id = adminGroup.Id,
            Name = adminGroup.Name,
            Pid = adminGroup.Pid,
            Createtime = adminGroup.Createtime,
            Updatetime = adminGroup.Updatetime,
            Status = adminGroup.Status,
            Permissions = adminGroup.Permissions.SplitToIntList().ToList()
        };
    }
    /// <summary>
    /// 添加角色
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public async Task Add(AddSysRoleInput input)
    {
        //判断同名角色是否存在
        var isExist=await SugarContext.Instance.Queryable<SysRole>().AnyAsync(p=>p.Name == input.Name);
        if (isExist)
            throw new ApiException($"[{input.Name}]角色名已存在,请重新命名");
        var adminGroup= input.Adapt<SysRole>();
        adminGroup.Permissions = string.Join(",", input.Permissions);
        await SugarContext.Instance.Insertable(adminGroup).ExecuteCommandAsync();
    }
    /// <summary>
    /// 删除角色
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    public async Task Delete(List<int> ids)
    {
        if (ids.Count == 0)
            throw new ApiException("参数不能为空");
        //获取待删除角色集合
        var adminGroups= await SugarContext.Instance.Queryable<SysRole>().Where(p => ids.Contains(p.Id)).ToListAsync();
        //判断删除数据与传入数据总数是否一致
        if (ids.Count != adminGroups.Count)
            throw new ApiException("传入数据与操作数据不一致,请刷新再试");
        await SugarContext.Instance.Deleteable<SysRole>(adminGroups).ExecuteCommandAsync();
    }
    /// <summary>
    /// 编辑角色
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public async Task Edit(EditSysRoleInput input)
    {
        var editGroup = await SugarContext.Instance.Queryable<SysRole>().FirstAsync(p => p.Id == input.id);
        _ = editGroup ?? throw new ApiException("当前查询无数据");
        var isExist = await SugarContext.Instance.Queryable<SysRole>().AnyAsync(p => p.Name == input.Name&&p.Id!=input.id);
        if (isExist)
            throw new ApiException($"[{input.Name}]角色名已存在,请重新命名");
        //数组转字符串
        var rules = string.Join(",", input.Permissions);
        var adminGroup=input.Adapt<SysRole>();
        adminGroup.Permissions = string.Join(",", input.Permissions);
        await SugarContext.Instance.Updateable<SysRole>(adminGroup)
                                   .IgnoreColumns(p=>new {p.Createtime})
                                   .Where(p=>p.Id==input.id)
                                   .ExecuteCommandAsync();
    }
}
